package com.zhang.redis.aspect;

import com.zhang.redis.util.RedissonManager;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

/**
 * description
 *
 * @author zhangFanJun
 * @date 2024-01-16 19:36
 **/
@Slf4j
@Aspect
@Component
public class RedisLockAop {

    @Resource
    private RedissonManager redissonManager;

    @Around("@annotation(redisLock)")
    public Object redisLock(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (Objects.isNull(requestAttributes)) {
            return joinPoint.proceed();
        }
        long waitTime = redisLock.waitTime() == 0 ? redisLock.time() : redisLock.waitTime();
        long leaseTime = redisLock.leaseTime() == 0 ? redisLock.time() : redisLock.leaseTime();
        AtomicReference<Object> res = new AtomicReference<>();
        redissonManager.tryLock(redisLock.key(), waitTime, leaseTime, () -> {
            log.info("redisLock:===》");
            res.set(joinPoint.proceed());
        });
        return res.get();
    }
}
